#include "CharacterDrawer.h"
#include "GFuns.h"

CharacterDrawer::CharacterDrawer(int aTileSize)
	: tileSize(aTileSize),
		s(tileSize)
{
	arm = al_create_bitmap(17,8);
	leg = al_create_bitmap(17,8);
	body = al_create_bitmap(20,24);
	head = al_create_bitmap(25,50);
	hand = al_create_bitmap(8,8);
	foot = al_create_bitmap(10,7);
	dress = al_create_bitmap(17,30);

	hairBuf = al_create_bitmap(15,8);
	hairBuf2 = al_create_bitmap(25,25);

	actualCharacter = NULL;

	characterColorSet.push_back(color.Clenium);
	characterColorSetB.push_back(color.CleniumD);
	characterColorSet.push_back(color.Cgold);
	characterColorSetB.push_back(color.CgoldD);
	characterColorSet.push_back(color.Cgreen);
	characterColorSetB.push_back(color.CgreenD);
	characterColorSet.push_back(color.Cleather);
	characterColorSetB.push_back(color.CleatherD);
	characterColorSet.push_back(color.Cpurple);
	characterColorSetB.push_back(color.CpurpleD);
	characterColorSet.push_back(color.Cblue);
	characterColorSetB.push_back(color.CblueD);
	characterColorSet.push_back(color.Cblack);
	characterColorSetB.push_back(color.CblackD);
	characterColorSet.push_back(color.Cbrown);
	characterColorSetB.push_back(color.CbrownD);
	characterColorSet.push_back(color.Cpink);
	characterColorSetB.push_back(color.CpinkD);
	characterColorSet.push_back(color.Cred);
	characterColorSetB.push_back(color.CredD);

	hairColorSet.push_back(color.Hblonde);
	hairColorSetB.push_back(color.HblondeD);
	hairColorSet.push_back(color.Hbrown);
	hairColorSetB.push_back(color.HbrownD);
	hairColorSet.push_back(color.Hdark);
	hairColorSetB.push_back(color.HdarkD);
	hairColorSet.push_back(color.Hred);
	hairColorSetB.push_back(color.HredD);
	hairColorSet.push_back(color.Hwhite);
	hairColorSetB.push_back(color.HwhiteD);
}

CharacterDrawer::~CharacterDrawer()
{
	al_destroy_bitmap(arm);
	al_destroy_bitmap(leg);
	al_destroy_bitmap(body);
	al_destroy_bitmap(head);
	al_destroy_bitmap(hand);
	al_destroy_bitmap(foot);
	al_destroy_bitmap(dress);

	al_destroy_bitmap(hairBuf);
	al_destroy_bitmap(hairBuf2);
}

void CharacterDrawer::GetRandomClothColor(ALLEGRO_COLOR& aCol, ALLEGRO_COLOR& aColB)
{
	int rnd = rand()%(characterColorSet.size());
	aCol = characterColorSet[rnd];
	aColB = characterColorSetB[rnd];
}

void CharacterDrawer::GetHairColor(ALLEGRO_COLOR& aCol, ALLEGRO_COLOR& aColB)
{
	int colNum = actualCharacter->hairColor;
	aCol = hairColorSet[colNum];
	aColB = hairColorSetB[colNum];
}

void CharacterDrawer::GenerateCharacterColor()
{
	GetRandomClothColor(characterColor, characterColorB);
}

void CharacterDrawer::GenerateCharacterSkinColor()
{
	ALLEGRO_COLOR race[] = {color.skinWhite, color.skinBlack, color.skinNord};
	ALLEGRO_COLOR raceB[] = {color.skinWhiteD, color.skinBlackD, color.skinNordD};

	skinColor = race[0];
	skinColorB = raceB[0];
	if(actualCharacter->race == RACE_BLACK)
	{
		skinColor = race[1];
		skinColorB = raceB[1];
	}
	else if(actualCharacter->race == RACE_NORD)
	{
		skinColor = race[2];
		skinColorB = raceB[2];
	}
}

void CharacterDrawer::DrawLeftArm()
{
	al_draw_scaled_rotated_bitmap(arm, 
	  0, al_get_bitmap_height(arm)/2,
		positionX + leftArm->GetParent()->GetJointX(), positionY + leftArm->GetParent()->GetJointY(), 
		leftArm->GetRealLength() / al_get_bitmap_width(arm), leftArm->GetWidth() / al_get_bitmap_height(arm),
		leftArm->GetAngle()-PI/2, 0);

	al_draw_rotated_bitmap(hand,
		al_get_bitmap_width(hand)/2, al_get_bitmap_height(hand)/2,
		positionX + leftArm->GetJointX(), positionY + leftArm->GetJointY(),
		leftArm->GetAngle()-PI/2, 0);
}

void CharacterDrawer::DrawRightArm()
{
	al_draw_scaled_rotated_bitmap(arm,
		0, al_get_bitmap_height(arm)/2,
		positionX + rightArm->GetParent()->GetJointX(), positionY + rightArm->GetParent()->GetJointY(), 
		rightArm->GetRealLength() / al_get_bitmap_width(arm), rightArm->GetWidth() / al_get_bitmap_height(arm),
		rightArm->GetAngle()-PI/2, 0);

	al_draw_rotated_bitmap(hand,
		al_get_bitmap_width(hand)/2, al_get_bitmap_height(hand)/2,
		positionX + rightArm->GetJointX(), positionY + rightArm->GetJointY(),
		rightArm->GetAngle()-PI/2, 0);
}

void CharacterDrawer::DrawLeftLeg()
{
	al_draw_scaled_rotated_bitmap(leg, 
		0, al_get_bitmap_height(leg)/2, 
		positionX + leftLeg->GetParent()->GetJointX(), positionY + leftLeg->GetParent()->GetJointY(), 
		leftLeg->GetRealLength() / al_get_bitmap_width(leg), leftLeg->GetWidth() / al_get_bitmap_height(leg),
		leftLeg->GetAngle()-PI/2, 0);
}

void CharacterDrawer::DrawRightLeg()
{
	al_draw_scaled_rotated_bitmap(leg, 
		0, al_get_bitmap_height(leg)/2,
		positionX + rightLeg->GetParent()->GetJointX(), positionY + rightLeg->GetParent()->GetJointY(), 
		rightLeg->GetRealLength() / al_get_bitmap_width(leg), rightLeg->GetWidth() / al_get_bitmap_height(leg),
		rightLeg->GetAngle()-PI/2, ALLEGRO_FLIP_VERTICAL);
}

void CharacterDrawer::Draw(Character* aCharacter)
{
	actualCharacter = aCharacter;

	PushRand(actualCharacter->seed);

	GenerateCharacterSkinColor();
	GenerateCharacterColor();

	// Clothes parts rendering 
	RenderArm();
	RenderLeg();
	RenderBody();
	RenderHead();
	RenderHand();
	RenderFoot();
	RenderDress();

	// Skinning
	positionX = s/2;
	positionY = s - actualCharacter->skeleton->GetLeftLeg()->GetLength() + 3;
	//DrawSkeleton(aCharacter->skeleton.GetMedian(), posX, posY);

	// Shadow
	al_draw_filled_ellipse(positionX,positionY+actualCharacter->skeleton->GetLeftLeg()->GetLength(),s/5,s/12,color.shadowL);

	// Boots
	leftLeg = actualCharacter->skeleton->GetLeftLeg();
	rightLeg = actualCharacter->skeleton->GetRightLeg();

	al_draw_rotated_bitmap(foot, al_get_bitmap_width(foot)/2, al_get_bitmap_height(foot)/2,
													 positionX + leftLeg->GetJointX(), positionY + leftLeg->GetJointY(), leftLeg->GetAngle(), 0);
	al_draw_rotated_bitmap(foot, al_get_bitmap_width(foot)/2, al_get_bitmap_height(foot)/2,
													 positionX + rightLeg->GetJointX(), positionY + rightLeg->GetJointY(), rightLeg->GetAngle(), 0);

	// Legs
	if(actualCharacter->facing == LEFT)
	{
		DrawLeftLeg();
		DrawRightLeg();
	}
	else if(actualCharacter->facing == RIGHT)
	{
		DrawRightLeg();
		DrawLeftLeg();
	}
	else
	{
		if(leftLeg->GetLengthMultiplier() < rightLeg->GetLengthMultiplier())
		{
			DrawLeftLeg();
			DrawRightLeg();
		}
		else
		{
			DrawRightLeg();
			DrawLeftLeg();
		}
	}
	

	// Dress
	if(actualCharacter->HaveDress())
	{
		Bone* bottom = actualCharacter->skeleton->GetSpine();
		float angle = (leftLeg->GetAngle()+ rightLeg->GetAngle() )/2 -PI/2;
		float length = ((leftLeg->GetRealLength()-3) + (rightLeg->GetRealLength()-3))/2 / al_get_bitmap_width(dress);
		al_draw_scaled_rotated_bitmap(dress, 0, al_get_bitmap_height(dress)/2, positionX + bottom->GetParent()->GetJointX(), positionY + bottom->GetParent()->GetJointY()-2, 
																length, (bottom->GetWidth()+10) / al_get_bitmap_height(dress),
																angle, ALLEGRO_FLIP_VERTICAL);
	}

	// Corps
	leftArm = actualCharacter->skeleton->GetLeftArm();
	rightArm = actualCharacter->skeleton->GetRightArm();

	// Back arm
	if(actualCharacter->facing == UP || actualCharacter->facing == DOWN)
	{
		DrawLeftArm();
		DrawRightArm();
	}
	if(actualCharacter->facing == LEFT) DrawLeftArm();
	if(actualCharacter->facing == RIGHT) DrawRightArm();

	// Body
	Bone* corps = actualCharacter->skeleton->GetSpine();
	al_draw_scaled_rotated_bitmap(body, 0, al_get_bitmap_height(body)/2, positionX + corps->GetX(), positionY + corps->GetY(), 
																corps->GetLength() / al_get_bitmap_width(body), corps->GetWidth() / al_get_bitmap_height(body),
																corps->GetAngle()-PI/2, 1);

	// Front arm
	if(actualCharacter->facing == LEFT) DrawRightArm();
	if(actualCharacter->facing == RIGHT) DrawLeftArm();

	// Head
	Bone* neck = actualCharacter->skeleton->GetNeck();
	al_draw_scaled_rotated_bitmap(head, al_get_bitmap_width(head)/2, al_get_bitmap_height(head)/2,
																positionX + neck->GetJointX(), positionY + neck->GetJointY(), 
																1,1,
																neck->GetAngle(), 0);

	actualCharacter->Refreshed();

	PopRand();
}

void CharacterDrawer::RenderBody()
{
	// Bitmaps
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	al_set_target_bitmap(body);
	int w = al_get_bitmap_width(body);
	int h = al_get_bitmap_height(body);

	// Useful variables
	bool up = actualCharacter->facing == UP ? true : false;
	bool male = actualCharacter->IsMale();

	// Naked chest
	draw_rectangle(0,0,w+2,h,skinColor,skinColorB,2);
	al_draw_filled_circle(w,h/2,2,hairColorSet[1]);
	if(male && !up)
	{
		int margin = 3;
		al_draw_line(margin,h/2,w/3-1,h/2,color.shadowL,2);
		al_draw_line(w/3,margin,w/3,h/2-1,color.shadowL,2);
		al_draw_line(w/3,h/2+1,w/3,h-margin,color.shadowL,2);
	}

	// Cloth

	// Siuts
	if(actualCharacter->HaveCloth(CLOTH_CASSOCK))
	{
		draw_rectangle(0,0,w+2,h,color.Cleather,color.CleatherD,2);
		al_draw_line(w-1,1,w-1,h-1,color.CgoldD,2);

		if(!up)
		{
			al_draw_line(1,1,w/2,h/2,color.Cgold,1);
			al_draw_line(1,h,w/2,h/2,color.Cgold,1);
			al_draw_filled_circle(w/2,h/2,2,color.Cgold);
		}
		else
		{
			draw_triangle(1,1,1,h,w/3,h/2,color.Cleather,color.CleatherD,1);
		}
	}

	if(actualCharacter->HaveCloth(CLOTH_KINGS_COAT))
	{
		draw_rectangle(0,0,w+2,h,color.CredD,color.CredD,2);
		draw_rectangle(1,1,h/6,h,color.Clenium,color.CleniumD,1);

		if(!up)
		{
			draw_rectangle(1,1,w+1,h/6,color.Cred,color.CredD,1);
			draw_rectangle(1,h*5/6,w+1,h,color.Cred,color.CredD,1);
			draw_rectangle(1,h/6,w+1,h*2/6,color.Clenium,color.CleniumD,1);
			draw_rectangle(1,h*4/6,w+1,h*5/6,color.Clenium,color.CleniumD,1);

			draw_rectangle(1,1,h/6,h,color.Clenium,color.CleniumD,1);
			draw_rectangle(1,h*2/6+1,w+1,h*4/6-1,color.CredD,color.CredD,1);
			al_draw_line(h/6,h/6,h/6,h*2/6,color.Clenium,1);
			al_draw_line(h/6,h*4/6,h/6,h*5/6,color.Clenium,1);
		}
		else
		{
			draw_rectangle(1,1,w+2,h,color.Cred,color.CredD,2);
			draw_rectangle(1,1,w/4,h,color.Clenium,color.CleniumD,1);
		}
	}

	if(actualCharacter->HaveCloth(CLOTH_ARMOR))
	{
		draw_rectangle(0,0,w,h,color.ironL,color.ironD,2);

		if(!up)
		{
			al_draw_line(3,h/2,w-3,h/2,color.shadowL,2);
			al_draw_line(w/3,3,w/3,h-3,color.shadowL,2);
		}
	}

	if(actualCharacter->HaveCloth(CLOTH_APRON_SMITH))
	{
		draw_rectangle(0,0,w,h,color.Cleather,color.CleatherD,2);

		draw_rectangle(0,0,w/2,h/6,skinColor,color.CleatherD,1);
		draw_rectangle(0,h*2/6,w/2,h*4/6,skinColor,color.CleatherD,1);
		draw_rectangle(0,h*5/6,w/2,h,skinColor,color.CleatherD,1);
	}

	if(actualCharacter->HaveCloth(CLOTH_APRON_HERB))
	{
		draw_rectangle(0,0,w,h,color.Cgreen,color.CgreenD,2);

		if(!up)
		{
			int r = h/2.5;
			draw_ellipse(0,h/2,r/1.5,r,skinColor,color.CgreenD,1);
		}
		draw_rectangle(w*5/6,1,w+1,h,color.Clenium,color.Clenium,1);
	}

	// Tops
	if(actualCharacter->HaveCloth(CLOTH_CHEMISE))
	{
		draw_rectangle(0,0,w,h,color.Clenium,color.CleniumD,2);

		if(!up)
		{
			draw_triangle(1,1,1,h,w/3,h/2,skinColor,color.CleniumD,1);
		}

		al_draw_line(w-1,1,w-1,h,color.Cleather,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_SHIRT))
	{
		draw_rectangle(0,0,w,h,characterColor,characterColorB,2);

		if(!up)
		{
			al_draw_line(0,h/2,w/2,h/2,color.shadowL,2);
		}

		al_draw_line(w-2,1,w-2,h,color.Cleather,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_DRESS))
	{
		draw_rectangle(0,0,w,h,characterColor,characterColorB,2);

		if(!up)
		{
			int r = h/2.5;
			draw_ellipse(0,h/2,r/1.5,r,skinColor,characterColorB,1);
		}

		ALLEGRO_COLOR belt;
		ALLEGRO_COLOR beltB;
		GetRandomClothColor(belt,beltB);
		draw_rectangle(w*3/4,1,w,h,belt,beltB,1);
	}

	if(actualCharacter->HaveCloth(CLOTH_BELT))
	{
		draw_rectangle(w*4/5,1,w,h,color.Cgold,color.CgoldD,1);
	}

	if(actualCharacter->HaveCloth(CLOTH_VEST))
	{
		ALLEGRO_COLOR vest;
		ALLEGRO_COLOR vestB;
		GetRandomClothColor(vest,vestB);

		if(!up)
		{
			draw_rectangle(1,1,w*2/3,h/3,vest,vestB,1);
			draw_rectangle(1,h*2/3,w*2/3,h,vest,vestB,1);
		}
		else
		{
			draw_rectangle(1,1,w*2/3,h,vest,vestB,1);
		}
	}

	// Naked women (for the boobs shade)
	if(!male && !up)
	{
		al_draw_arc(w/4,h/4,h/4,ALLEGRO_PI/2,-ALLEGRO_PI,color.shadowL,2);
		al_draw_arc(w/4,h*3/4,h/4,ALLEGRO_PI/2,-ALLEGRO_PI,color.shadowL,2);
	}

	// Return display
	al_set_target_bitmap(disp);
}

void CharacterDrawer::RenderDress()
{
	// Bitmaps
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	al_set_target_bitmap(dress);
	int w = al_get_bitmap_width(dress);
	int h = al_get_bitmap_height(dress);

	// Useful variables
	bool up = (actualCharacter->facing == UP);

	// Main dress color
	ALLEGRO_COLOR col = color.Clenium;
	ALLEGRO_COLOR colB = color.CleniumD;

	// Conditional dress color
	if(actualCharacter->HaveCloth(CLOTH_APRON_HERB))
	{
		col = color.Cgreen;
		colB = color.CgreenD;
	}
	else if(actualCharacter->HaveCloth(CLOTH_PETTICOAT))
	{
		col = color.CleniumD;
		colB = color.shadow;
	}
	else if(actualCharacter->HaveCloth(CLOTH_SKIRT) || actualCharacter->HaveCloth(CLOTH_DRESS))
	{
		col = characterColor;
		colB = characterColorB;
	}

	// Basic dress shape
	float a = h-15;
	float m = (h-a)/2;

	draw_rectangle(1,m,w,h-m,col,colB,2);

	draw_triangle(1,m,w,m,w,1,col,colB,2);
	draw_triangle(1,h-m,w,h-m,w,h,col,colB,2);
	al_draw_line(2,m,w-1,m,col,2);
	al_draw_line(2,h-m,w-1,h-m,col,2);

	// Shades
	al_draw_line(2,m+1,w,m/2,color.shadowLL,1);
	al_draw_line(2,h-m-1,w,h-m/2,color.shadowLL,1);
	al_draw_line(-2,h/2,w,m,color.shadowLL,1);
	al_draw_line(-2,h/2,w,h/2,color.shadowLL,1);
	al_draw_line(-2,h/2,w,h-m,color.shadowLL,1);

	// Conditional details
	if(actualCharacter->HaveCloth(CLOTH_APRON_HERB) && !up)
	{
		int r = a/2;
		draw_ellipse(0,h/2,r,r,color.Clenium,color.Clenium,1);
	}

	// Return display
	al_set_target_bitmap(disp);
}

void CharacterDrawer::RenderArm()
{
	// Bitmaps
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	al_set_target_bitmap(arm);
	int w = al_get_bitmap_width(arm);
	int h = al_get_bitmap_height(arm);

	// Useful variables
	bool male = actualCharacter->IsMale();

	// Naked arm
	draw_rectangle(0,0,w,h,skinColor,skinColorB,2);

	// Conditional drawing
	if(actualCharacter->HaveCloth(CLOTH_CASSOCK))
	{
		draw_rectangle(0,0,w,h,color.Cleather,color.CleatherD,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_KINGS_COAT))
	{
		draw_rectangle(0,0,w,h,color.Cred,color.CredD,2);
		draw_rectangle(w-h,1,w,h,color.Clenium,color.CleniumD,1);
	}

	if(actualCharacter->HaveCloth(CLOTH_ARMOR))
	{
		draw_rectangle(0,0,w,h,color.ironL,color.ironD,2);
		draw_rectangle(1,1,h,h,color.ironL,color.ironD,1);
		for(int i=h; i<w; i+=2)
		{
			al_draw_line(i,1,i,h,color.ironD,1);
		}
	}

	if(actualCharacter->HaveCloth(CLOTH_CHEMISE))
	{
		draw_rectangle(0,0,w/2,h,color.Clenium,color.CleniumD,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_SHIRT))
	{
		ALLEGRO_COLOR shirt;
		ALLEGRO_COLOR shirtB;
		GetRandomClothColor(shirt,shirtB);
		draw_rectangle(w/2,0,w,h,shirt,shirtB,2);
		draw_rectangle(0,0,w/2,h,characterColor,characterColorB,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_APRON_HERB))
	{
		draw_rectangle(0,0,w/3,h,color.Cgreen,color.CgreenD,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_DRESS))
	{
		draw_rectangle(0,0,w,h,characterColor,characterColorB,2);
	}

	// Return display
	al_set_target_bitmap(disp);
}

void CharacterDrawer::RenderLeg()
{
	// Bitmaps
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	al_set_target_bitmap(leg);
	int w = al_get_bitmap_width(leg);
	int h = al_get_bitmap_height(leg);

	// Useful variables
	int male = actualCharacter->IsMale();
	bool up = (actualCharacter->facing == UP);

	// Naked leg
	draw_rectangle(0,0,w,h,skinColor,skinColorB,2);

	// Conditional drawing
	if(actualCharacter->HaveCloth(CLOTH_CASSOCK))
	{
		draw_rectangle(-2,-2,w,h,color.Cleather,color.CleatherD,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_KINGS_COAT))
	{
		if(!up)
		{
			draw_rectangle(-2,-2,w,h,color.CredD,color.CredD,2);
			draw_triangle(-1,h/4,-1,h,w,h,color.Clenium,color.CleniumD,1);
			draw_triangle(-1,h*3/4,-1,h,w-h/4,h,color.Cred,color.CredD,1);
		}
		else
		{
			draw_rectangle(-2,-2,w,h,color.Cred,color.CredD,1);
			draw_rectangle(w/2,-2,w*3/4,h,color.Clenium,color.CleniumD,1);
			draw_rectangle(w*3/4+1,1,w,h,color.CredD,color.CredD,1);
		}
	}

	if(actualCharacter->HaveCloth(CLOTH_ARMOR))
	{
		draw_rectangle(0,0,w,h,color.ironL,color.ironD,2);
		draw_rectangle(w-h/2,1,w,h,color.ironL,color.ironD,1);
		for(int i=0; i<w-h/2; i+=2)
		{
			al_draw_line(i,1,i,h,color.ironD,1);
		}
	}

	if(actualCharacter->HaveCloth(CLOTH_PANTS))
	{
		draw_rectangle(0,0,w,h,color.Cleather,color.CleatherD,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_TROUSERS))
	{
		ALLEGRO_COLOR legs;
		ALLEGRO_COLOR legsB;
		GetRandomClothColor(legs,legsB);
		draw_rectangle(0,0,w,h,legs,legsB,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_APRON_SMITH))
	{
		draw_rectangle(-2,-2,w,h,color.Cleather,color.CleatherD,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_CHEMISE))
	{
		draw_rectangle(-2,-2,w/2,h,color.Clenium,color.CleniumD,2);
	}

	if(actualCharacter->HaveCloth(CLOTH_SHIRT))
	{
		draw_rectangle(-2,-2,w/2,h,characterColor,characterColorB,1);
	}

	// Return display
	al_set_target_bitmap(disp);
}

void CharacterDrawer::RenderHead()
{
	// Bitmaps
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	al_set_target_bitmap(head);
	al_clear_to_color(color.blank);
	int w = al_get_bitmap_width(head);
	int h = al_get_bitmap_height(head);

	// Useful variables
	int mood = actualCharacter->mood;
	int race = actualCharacter->race;
	int age = actualCharacter->age;
	bool male = actualCharacter->IsMale();
	int hairStyle = actualCharacter->hairCut;
	int facing = actualCharacter->facing;
	int brownLen = 4;
	int eyeStare = 0;
	if(facing == LEFT) eyeStare = -2;
	else if(facing == RIGHT) eyeStare = 2;
	int r = w/3+1; // head width
	int eyeDelay = r/3;
	int eyeR = r/8;

	// Hair color
	ALLEGRO_COLOR hair;
	ALLEGRO_COLOR hairB;
	GetHairColor(hair,hairB);

	// Hair behind
	if(!male)
	{
		if(hairStyle == HAIR_HIME)
		{
			draw_rectangle(w/2-r,h/2,w/2+r+1,h/2+r,hair,hairB,1);
		}
		else if(hairStyle == HAIR_LONG)
		{
			int boundH = h/2+r+2;
			int cy = h/2+r/2;
			int mr = boundH - cy;
			draw_ellipse(w/2-r+2,cy,3,mr,hair,hairB,1);
			draw_ellipse(w/2+r-2,cy,3,mr,hair,hairB,1);
			draw_triangle(w/2-r+2,boundH,w/2-r,boundH+mr*1.2,w/2-r+5,boundH+mr*1.2,hair,hairB,1);
			draw_triangle(w/2+r-2,boundH,w/2+r,boundH+mr*1.2,w/2+r-4,boundH+mr*1.2,hair,hairB,1);
			draw_ellipse(w/2-r+2,boundH,2,2,color.Cgold,color.CgoldD,1);
			draw_ellipse(w/2+r-2,boundH,2,2,color.Cgold,color.CgoldD,1);
		}
	}

	// Plain head
	if(!(!male && facing == UP)) draw_ellipse(w/2,h/2,r,r,skinColor,skinColorB,1.5);
	else draw_ellipse(w/2,h/2,r,r,hair,hairB,1);

	// Wrinkles
	if(age == AGE_OLD && facing != UP)
	{
		al_draw_line(w/2-eyeDelay+1,h/2-r*2/3,w/2+eyeDelay-1,h/2-r*2/3,color.shadowL,1);
		al_draw_line(w/2-eyeDelay,h/2-r*2/3+2,w/2+eyeDelay,h/2-r*2/3+2,color.shadowL,1);

		al_draw_line(w/2-eyeDelay-2,h/2-2,w/2-eyeDelay-2,h/2+2,color.shadowL,1);
		al_draw_line(w/2+eyeDelay+3,h/2-2,w/2+eyeDelay+3,h/2+2,color.shadowL,1);
	}

	// Hair in front
	if(male)
	{
		if(hairStyle == HAIR_MOHAWK)
		{
			int mohawkW = r/2;
			if(facing != UP) draw_rectangle(w/2-mohawkW/2,h/2-r-mohawkW/2,w/2+mohawkW/2,h/2-r+mohawkW,hair,hairB,1);
			else draw_rectangle(w/2-mohawkW/2,h/2-r-mohawkW/2,w/2+mohawkW/2,h*2/3,hair,hairB,1);
		}

		else if(hairStyle == HAIR_UNDERCUT)
		{
			al_set_target_bitmap(hairBuf2);
			al_clear_to_color(color.blank);
			int hw = al_get_bitmap_width(hairBuf2);
			int hh = al_get_bitmap_height(hairBuf2);

			int cutH;
			if(facing != UP) cutH = hh/2-3;
			else cutH = hh/2;

			draw_ellipse(hw/2,hh/2,r,r,hair,hairB,1);
			draw_rectangle(0,cutH,w,hh,color.mpink,color.mpink,1);
			al_draw_line(hw/2-r,cutH,hw/2+r,cutH,hairB,1);

			if(facing != UP) al_draw_line(hw/2,cutH,hw/2,cutH-3,color.mpink,2);

			noise(color.mpink,color.blank,1);

			al_set_target_bitmap(head);
			al_draw_bitmap(hairBuf2,0,h/4-1,0);
		}

		else if(hairStyle == HAIR_SHORT)
		{
			int lh = r/2+2;
			int lw = r/2+2;
			int ld = r/2;

			int x1 = w/2-r;
			int x2 = x1+lw;
			int x4 = x1+r*2;
			int x3 = x4-lw;

			int y1 = h/2-r-2;
			int y3 = y1+lh;
			int y4 = y3+ld;
			int y2 = y1+ld;

			if(facing == UP) 
			{
				y4 *= 1.4;
				y3 *= 1.4;

				int t = y4;
				y4 = y3;
				y3 = t;
			}

			Node left[] = {{x1,y2},{x1,y4},{x2,y1},{x2,y3}};
			draw_quad(left,hair,hairB,1);
			Node right[] = {{x4,y2},{x4,y4},{x3,y1},{x3,y3}};
			draw_quad(right,hair,hairB,1);
			draw_rectangle(x2,y1,x3,y3,hair,hairB,1);

			if(rand()%2 == 0) al_draw_line(x2,y1+1,x2,y3-1,hair,1);
			else al_draw_line(x3,y1+1,x3,y3-1,hair,1);

		}
	}
	else
	{
		if(hairStyle == HAIR_ODANGO || hairStyle == HAIR_PIGTAILS)
		{
			al_set_target_bitmap(hairBuf);
			al_clear_to_color(color.blank);
			int hw = al_get_bitmap_width(hairBuf);
			int hh = al_get_bitmap_height(hairBuf);
			draw_ellipse(hw/2,hh/2,hw/2-1,hh/2-1,hair,hairB,1);

			al_set_target_bitmap(head);
			al_draw_rotated_bitmap(hairBuf,hw/2,hh/2,w/2-r/2-1,h/2-r/2-2,-ALLEGRO_PI/4,0);
			al_draw_rotated_bitmap(hairBuf,hw/2,hh/2,w/2+r/2+1,h/2-r/2-2,ALLEGRO_PI/4,0);

			if(hairStyle == HAIR_ODANGO)
			{
				draw_ellipse(w/2-r,h/2-r,3,3,hair,hairB,1);
				draw_ellipse(w/2+r,h/2-r,3,3,hair,hairB,1);
			}
			else if(hairStyle == HAIR_PIGTAILS)
			{
				draw_triangle(w/2-r+1,h/2-3,0,h/2,w/2-r+2,h/2+6,hair,hairB,1);
				draw_triangle(w/2+r-1,h/2-3,w,h/2,w/2+r-2,h/2+6,hair,hairB,1);
			}
		}

		else if(hairStyle == HAIR_HIME || hairStyle == HAIR_LONG)
		{
			if(facing != UP)
			{
				al_set_target_bitmap(hairBuf2);
				al_clear_to_color(color.blank);
				int hw = al_get_bitmap_width(hairBuf2);
				int hh = al_get_bitmap_height(hairBuf2);
				int cutH = hh/2-3;
				draw_ellipse(hw/2,hh/2,r,r,hair,hairB,1);
				draw_rectangle(0,cutH,w,hh,color.mpink,color.mpink,1);
				al_draw_line(hw/2-r,cutH,hw/2+r,cutH,hairB,1);
				al_draw_line(hw/2-r/2,cutH,hw/2-r/2+2,cutH-3,color.mpink,1);
				al_draw_line(hw/2+r/2,cutH,hw/2+r/2-2,cutH-3,color.mpink,1);

				noise(color.mpink,color.blank,1);

				al_set_target_bitmap(head);
				al_draw_bitmap(hairBuf2,0,h/4,0);
			}
			else
			{
				draw_rectangle(w/2-r+1,h/2,w/2+r,h/2+r-1,hair,hair,1);
				al_draw_line(w/2-r/2,h/2+r,w/2-r/3,h/2,hairB,1);
				al_draw_line(w/2+r/2,h/2+r,w/2+r/3,h/2,hairB,1);
				al_draw_line(w/2,h/2+r,w/2,h/2+r/3,hairB,1);
			}
		}
	}

	// Face
	if(facing != UP)
	{
		draw_ellipse(w/2-eyeDelay+eyeStare,h/2,eyeR,eyeR*2,color.black,color.black,1);
		draw_ellipse(w/2+eyeDelay+eyeStare,h/2,eyeR,eyeR*2,color.black,color.black,1);

		if(mood == MOOD_ANGRY)
		{
			al_draw_line(w/2-eyeDelay-brownLen/2+eyeStare,h/2-eyeR*2-brownLen/2,w/2-eyeDelay+brownLen/2+eyeStare,h/2-eyeR*2,color.black,1);
			al_draw_line(w/2+eyeDelay+brownLen/2+eyeStare,h/2-eyeR*2-brownLen/2,w/2+eyeDelay-brownLen/2+eyeStare,h/2-eyeR*2,color.black,1);

			al_draw_line(w/2-eyeDelay,h/2+r*2/3,w/2+eyeDelay,h/2+r*2/3,color.black,1);
		}
		if(mood == MOOD_SAD)
		{
			al_draw_line(w/2-eyeDelay-brownLen/2+eyeStare,h/2-eyeR*2,w/2-eyeDelay+brownLen/2+eyeStare,h/2-eyeR*2-brownLen/2,color.black,1);
			al_draw_line(w/2+eyeDelay+brownLen/2+eyeStare,h/2-eyeR*2,w/2+eyeDelay-brownLen/2+eyeStare,h/2-eyeR*2-brownLen/2,color.black,1);

			al_draw_line(w/2-eyeDelay-1,h/2+6,w/2,h/2+5,color.black,1);
			al_draw_line(w/2+eyeDelay+1,h/2+6,w/2,h/2+5,color.black,1);
		}
		if(mood == MOOD_HAPPY)
		{
			al_draw_line(w/2-eyeDelay-1,h/2+4,w/2,h/2+6,color.black,1);
			al_draw_line(w/2+eyeDelay+1,h/2+4,w/2,h/2+6,color.black,1);
		}
		if(mood == MOOD_LAUGH)
		{
			al_draw_line(w/2-eyeDelay-1,h/2+3,w/2,h/2+5,color.black,1);
			al_draw_line(w/2+eyeDelay+1,h/2+3,w/2,h/2+5,color.black,1);
			al_draw_line(w/2-eyeDelay-1,h/2+4,w/2,h/2+8,color.black,1);
			al_draw_line(w/2+eyeDelay+1,h/2+4,w/2,h/2+8,color.black,1);
		}
		if(mood == MOOD_SUPRISED)
		{
			draw_ellipse(w/2,h/2+5,2,2,color.black,color.black,1);
		}
		if(mood == MOOD_NONE)
		{
			al_draw_line(w/2-eyeDelay+1,h/2+r*2/3,w/2+eyeDelay-1,h/2+r*2/3,color.black,1);
		}
	}

	// Hats
	if(actualCharacter->HaveCloth(CLOTH_CASSOCK))
	{
		draw_rounded_rectangle(w/2-r,h/2-6,w/2+r+1,h/2-3,1,1,hair,hairB,1);
	}

	if(actualCharacter->HaveCloth(CLOTH_ARMOR))
	{
		al_clear_to_color(color.blank);
		draw_ellipse(w/2,h/2,r,r,color.ironL,color.ironD,1);
		draw_rectangle(w/2-r+1,h/2,w/2+r,h/2+r,color.ironL,color.ironD,1);
		al_draw_line(w/2-r+1,h/2,w/2+r-1,h/2,color.ironL,1);

		if(facing != UP)
		{
			float helmW = 2;
			float helmX = w/2;
			float holeLeft = w/2-r*2/3;
			float holeRight = w/2+r*2/3;
			if(facing == LEFT)
			{
				helmX = w*2/5;
				holeRight = w/2+2;
			}
			if(facing == RIGHT)
			{
				helmX = w*3/5;
				holeLeft = w/2-2;
			}
			draw_rectangle(holeLeft,h/2-helmW/2,holeRight,h/2+helmW/2,color.black,color.ironD,1);
			draw_rectangle(helmX-helmW/2,h/2+helmW/2,helmX+helmW/2,h/2+r,color.black,color.ironD,1);
			al_draw_line(w/2-helmW/2,h/2+helmW/2-1,w/2+helmW/2-1,h/2+helmW-1,color.black,1);
		}

		draw_ellipse(w/2,h/2-r,3,5,color.Cred,color.CredD,1);
	}

	if(actualCharacter->HaveCloth(CLOTH_KINGS_COAT))
	{
		float botH = h/2-r/3;
		float topH = h/2-r;
		float crownStep = r*2/3;

		draw_rectangle(w/2-r+1,topH,w/2+r,botH,color.Cgold,color.CgoldD,1);
		draw_triangle(w/2-r+1,topH-crownStep+2,w/2-r+1,topH,w/2-crownStep/2,topH,color.Cgold,color.CgoldD,1);
		draw_triangle(w/2+r,topH-crownStep+1,w/2+r,topH,w/2+crownStep/2,topH,color.Cgold,color.CgoldD,1);
		draw_triangle(w/2,topH-crownStep,w/2-crownStep/2,topH,w/2+crownStep/2,topH,color.Cgold,color.CgoldD,1);
		al_draw_line(w/2-r+1,topH,w/2+r-1,topH,color.Cgold,1);

		draw_ellipse(w/2,(topH+botH)/2-1,2,2,color.Cred,color.CredD,1);
		draw_ellipse(w/2-crownStep,(topH+botH)/2-1,2,2,color.Cgreen,color.CgreenD,1);
		draw_ellipse(w/2+crownStep,(topH+botH)/2-1,2,2,color.Cgreen,color.CgreenD,1);

		al_draw_line(w/2-r,botH+1,w/2+r,botH+1,color.shadowL,1);
	}

	if(actualCharacter->HaveCloth(CLOTH_HAT))
	{
		int mr = r*2/3;
		draw_ellipse(w/2,h/2-r/2-1,mr,mr/3,color.Clenium,color.CleniumD,1);
		draw_ellipse(w/2,h/2-r,mr*1.5,mr/2+1,color.Clenium,color.CleniumD,1);
	}

	// Return display
	al_set_target_bitmap(disp);
}

void CharacterDrawer::RenderFoot()
{
	// Bitmaps
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	al_set_target_bitmap(foot);
	int w = al_get_bitmap_width(foot);
	int h = al_get_bitmap_height(foot);

	// Useful variables
	int job = actualCharacter->job;

	// Sandals
	ALLEGRO_COLOR col = color.Cleather;
	ALLEGRO_COLOR colB = color.CleatherD;

	// Conditional drawing
	if(actualCharacter->HaveCloth(CLOTH_ARMOR))
	{
		col = color.iron;
		colB = color.ironD;
	}

	// Render
	draw_ellipse(w/2,h/2,w/2-1,h/2-1,col,colB,1);

	// Return display
	al_set_target_bitmap(disp);
}

void CharacterDrawer::RenderHand()
{
	// Bitmaps
	ALLEGRO_BITMAP* disp = al_get_target_bitmap();
	al_set_target_bitmap(hand);
	int w = al_get_bitmap_width(hand);
	int h = al_get_bitmap_height(hand);

	// Useful variables
	int job = actualCharacter->job;

	// Naked hands
	ALLEGRO_COLOR col = skinColor;
	ALLEGRO_COLOR colB = skinColorB;

	// Conditional drawing
	if(actualCharacter->HaveCloth(CLOTH_ARMOR))
	{
		col = color.iron;
		colB = color.ironD;
	}

	// Render
	draw_ellipse(w/2,h/2,w/2-1,h/2-1,col,colB,1);

	// Return display
	al_set_target_bitmap(disp);
}

// Only for debugging
void CharacterDrawer::DrawSkeleton(Bone* aBone, int aBaseX, int aBaseY)
{
	if(aBone->GetParent() != NULL) 
	{
		al_draw_line(aBaseX + aBone->GetJointX(), aBaseY + aBone->GetJointY(),
								 aBaseX + aBone->GetX(), aBaseY + aBone->GetY(),
								 color.black, 1);
		al_draw_filled_circle(aBaseX + aBone->GetJointX(), aBaseY + aBone->GetJointY(),2,color.black);
	}

	for(int i=0; i<aBone->GetChildCount(); i++)
	{
		DrawSkeleton(aBone->GetChild(i), aBaseX, aBaseY);
	}
}